<div class="sticky-block-box" id="catalog">
  <div class="catalog-block pure">
    <nav class="article-catalog">
      <div class="catalog-title">目录</div>
      <div class="catalog-body">
        <ul class="catalog-list" style="margin-top:0px;">
        </ul>
      </div>
    </nav>
  </div>
</div>

<div id="custom-bottom" style="display: none;">
  <div id="custom-btm" class="custom-bottom-box" title="滚到底部"></div>
  <div id="custom-edit" class="custom-bottom-box" title="编辑"></div>
  <div id="custom-top" class="custom-bottom-box" title="回到顶部"></div>
</div>

<script src="//cdn.jsdelivr.net/npm/highlightjs-line-numbers.js@2.8.0/dist/highlightjs-line-numbers.min.js"></script>
<script>
  function delete_eles(list) {
    for (const e of list) {
      try {
        document.getElementById(e).remove()
      } catch (e) {
        continue
      }
    }
  }

  /* 删除评论块下面多余内容 */
  let delete_ids = ["ad_text_under_commentbox", "ad_t2", "opt_under_post", "cnblogs_c1", "under_post_card1",
    "cnblogs_c2", "under_post_card2", "HistoryToday"
  ]
  delete_eles(delete_ids)

  let topics = document.getElementById('topics')
  let titleEle = document.getElementsByClassName('postTitle')[0]
  let sideBar = document.getElementById('sideBarMain')

  function hideCatalog() {
    if (topics.getBoundingClientRect().x < 240) {
      document.getElementById("catalog").setAttribute("style", "display: none;")
    }
  }

  if (document.getElementById("topics")) {
    /* markdown模式下为代码加入行号, 调用插件highlightjs-line-numbers.js */
    hljs.initLineNumbersOnLoad();
  }

  var browser = {

    versions: function () {
      var u = navigator.userAgent,
        app = navigator.appVersion;
      return { //移动终端浏览器版本信息
        trident: u.indexOf('Trident') > -1, //IE内核
        presto: u.indexOf('Presto') > -1, //opera内核
        webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
        gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
        mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
        ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
        android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或uc浏览器
        iPhone: u.indexOf('iPhone') > -1, //是否为iPhone或者QQHD浏览器
        iPad: u.indexOf('iPad') > -1, //是否iPad
        webApp: u.indexOf('Safari') == -1 //是否web应该程序，没有头部与底部
      };
    }(),

    language: (navigator.browserLanguage || navigator.language).toLowerCase()

  }

  if (!browser.versions.mobile) {

    if (!document.getElementById("topics")) {
      document.getElementById("catalog").remove()
      document.getElementById("custom-bottom").remove()
    }

    function generateCatalog() {
      let contentBody = document.getElementById('cnblogs_post_body')

      let hs = new Array
      for (var i = 0; i < contentBody.children.length; i++) {
        let e = contentBody.children[i]
        switch (e.tagName) {
          case "H2":
            hs.push(e)
            break
          case "H3":
            hs.push(e)
            break
          case "H4":
            hs.push(e)
            break
          case "H5":
            hs.push(e)
            break
          case "H6":
            hs.push(e)
            break
        }
      }

      let html = ''
      let curr, last = 0
      hs.forEach((e) => {
        curr = e.tagName[1]
        if (last) {
          if (curr == last) {
            html += "</li>"
            html += '<li class="catalog h' + curr + '">'
            html += '<a href="#' + e.getAttribute("id") + '">' + e.innerText + '</a>'
          } else if (curr > last) {
            html += '<ul class="sub-list">'
            html += '<li class="catalog h' + curr + '">'
            html += '<a href="#' + e.getAttribute("id") + '">' + e.innerText + '</a>'
          } else {
            for (let i = 0; i < last - curr; i++) {
              html += '</ul>'
              html += '</li>'
            }
            html += '<li class="catalog h' + curr + '">'
            html += '<a href="#' + e.getAttribute("id") + '">' + e.innerText + '</a>'
          }
        } else {
          html += '<li class="catalog h' + curr + '">'
          html += '<a href="#' + e.getAttribute("id") + '">' + e.innerText + '</a>'
        }
        last = curr
      })
      for (let i = 0; i < last - 2; i++) {
        html += '</ul>'
        html += '</li>'
      }
      return html
    }

    if (document.getElementById("topics")) {
      let catalogList = $('.catalog-list')[0]
      let html = generateCatalog()
      if (html) {
        catalogList.innerHTML += generateCatalog()
        hideCatalog()
      } else {
        document.getElementById("catalog").remove()
      }
    }

    /* 添加滚动事件
        保证目录top不超过正文 
        保证右下角浮动块不超过右边栏
    */
    // window.addEventListener('scroll', winScroll);
    function winScroll(e) {
      let style = document.getElementById("catalog").getAttribute("style")
      if (document.getElementById("catalog") && style !== "display: none;") {

        let hs = document.querySelectorAll(
          "#cnblogs_post_body h2, #cnblogs_post_body h3, #cnblogs_post_body h4, #cnblogs_post_body h5, #cnblogs_post_body h6"
        )

        for (const e of hs) {
          if (e.getBoundingClientRect().y >= 0) {
            /* 将目录中对应的最上面h标签的a标签标记为active，移除之前的active */
            let pre = document.querySelector(".catalog-list li.active")
            if (pre) {
              pre.classList.remove("active")
            }
            // 查找对应的a标签
            let curr = document.querySelector("a[href='#" + e.getAttribute("id") + "']")
            curr.parentElement.classList.add("active")
            break
          }
        }


        /* 目录滚动 */
        style = style ? style : ""
        style = style.replace(/top:\s?\S+px;/g, "")
        let bottom = titleEle.getBoundingClientRect().bottom
        if (bottom >= 20) {
          document.getElementById("catalog").setAttribute("style", "top:" + bottom + "px;" + style.replace())
        } else {
          document.getElementById("catalog").setAttribute("style", "top: 20px;" + style)
        }
        hideCatalog()
      }


      if (document.getElementById("topics")) {
        /* 右下解浮动块滚动 */
        let bottom = sideBar.getBoundingClientRect().bottom
        let height = window.innerHeight
        if (height - bottom < 192) {
          document.getElementById("custom-bottom").setAttribute("style", "display: none;")
        } else {
          document.getElementById("custom-bottom").setAttribute("style", "right: initial; left: " + (topics
            .getBoundingClientRect().x + topics.getBoundingClientRect().width + 20) + "px")
        }
      } else {
        document.getElementById("custom-bottom").setAttribute("style", "display: none;")
      }
    }

    $("#custom-bottom").on("click", "#custom-edit", (e) => {
      document.querySelector('a[rel="nofollow"]').click()
    })

    $("#custom-bottom").on("click", "#custom-top", (e) => {
      let html = location.href.split("#")[0] + "#top"
      location.href = html
    })

    $("#custom-bottom").on("click", "#custom-btm", (e) => {
      let html = location.href.split("#")[0] + "#footer"
      location.href = html
    })
  } else {
    document.getElementById("sideBarMain").remove()
    document.getElementById("catalog").remove()
  }

  window.onscroll = winScroll

  window.onresize = function (e) {
    if (topics.getBoundingClientRect().x < 244) {
      document.getElementById("catalog").setAttribute("style", "display: none;")
    } else {
      let style = "left: " + (topics.getBoundingClientRect().x - 230 - 14) + "px;"
      let bottom = titleEle.getBoundingClientRect().bottom
      if (bottom >= 0) {
        style += "top:" + bottom + "px;"
      } else {
        style += "top: 20px;"
      }
      document.getElementById("catalog").setAttribute("style", style)
    }

    if (document.getElementById("custom-bottom").getAttribute("style") !== "display: none;") {
      document.getElementById("custom-bottom").setAttribute("style", "right: initial; left: " + (topics
        .getBoundingClientRect().x + topics.getBoundingClientRect().width + 20) + "px;")
    }
  }

  /* 删除边栏没用的部分 */
  $("#sideBar").bind("DOMNodeInserted", function () {
    let delete_sidebar_ids = ["sidebar_news", "blog-calendar", "catListEssay", "sidebar_recentposts",
      "sidebar_postarchive",
      "sidebar_recentcomments", "sidebar_topviewedposts"
    ]
    delete_eles(delete_sidebar_ids)
  })
</script>